package com.iceland.server.server.cmd;

import com.iceland.common.exception.GlobalExceptionHandler;
import com.iceland.common.message.CmdMessagEncoder;
import com.iceland.common.message.CmdMessageDecoder;
import com.iceland.common.rpc.MethodInvocationResponseStrategy;
import com.iceland.common.rpc.MethodInvocationStrategy;
import com.iceland.common.rpc.RemoteServiceScanner;
import com.iceland.common.rpc.RpcServiceClassFactory;
import com.iceland.common.strategy.CmdStrategyFactory;
import com.iceland.common.thread.MessageEventExcutor;
import com.iceland.server.config.Environment;
import com.iceland.server.config.ProxyConfig;
import com.iceland.server.server.Server;
import com.iceland.server.server.cmd.strategy.CmdChannelConnectStrategy;
import com.iceland.server.server.cmd.strategy.ForwardStrategy;
import com.iceland.server.server.cmd.strategy.ProxyChannelConnectStrategy;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;

import java.util.List;


/**
 * 客户端配套服务器
 */
@Slf4j
public class CmdServer extends Server {

    static {
        ProxyConfig proxyConfig = Environment.getProxyConfig();
        //设置线程数
        MessageEventExcutor.setCorePoolSize(proxyConfig.getCoreMessageEventThreadSize());
        MessageEventExcutor.setMaxPoolSize(proxyConfig.getMaxMessageEventThreadSize());
        //扫描服务接口
        RemoteServiceScanner.scan(null);
        log.info("扫描服务接口:{}",RemoteServiceScanner.getInterfaceClass());
        log.info("扫描服务实例:{}",RemoteServiceScanner.getInstanceClass());

        List<Class> instanceClass = RemoteServiceScanner.getInstanceClass();
        instanceClass.forEach(x->{
            RpcServiceClassFactory.putBean(x);
        });
        log.info("载入服务实例:{}",RemoteServiceScanner.getInstanceClass());

        log.info("初始化CmdStrategyFactory，载入策略CmdChannelConnectStrategy、ForwardStrategy、ProxyChannelConnectStrategy、MethodInvocationStrategy、MethodInvocationResponseStrategy");
        CmdStrategyFactory.addCmdStrategy(new CmdChannelConnectStrategy());
        CmdStrategyFactory.addCmdStrategy(new ForwardStrategy());
        CmdStrategyFactory.addCmdStrategy(new ProxyChannelConnectStrategy());
        CmdStrategyFactory.addCmdStrategy(new MethodInvocationStrategy());
        CmdStrategyFactory.addCmdStrategy(new MethodInvocationResponseStrategy());
    }

    public CmdServer() {
        super(1,2, NioServerSocketChannel.class);
    }

    public CmdServer(int bossThreadCount, int workThreadCount, Class channelClass) {
        super(bossThreadCount, workThreadCount, channelClass);
    }

    @Override
    protected void preStart(ServerBootstrap sb) {
        sb.childHandler(new ChannelInitializer<SocketChannel>() { // (4)
            @Override
            public void initChannel(SocketChannel ch) throws Exception {
                //out:逆序执行
                ch.pipeline().addFirst(new CmdMessagEncoder());

                //in：顺序执行
                ch.pipeline().addLast(new CmdMessageDecoder(),new CmdMessageHandler());
                ch.pipeline().addLast(new GlobalExceptionHandler());


            }
        });
    }

    @Override
    protected void afterStart() {

    }
}
